//
//  miscellaneous.cpp
//  HelloWorld
//
//  Created by Kevin Tang on 7/1/15.
//  Copyright (c) 2015年 Kevin Tang. All rights reserved.
//
#include <iostream>
#include <typeinfo>
#include "miscellaneous.h"
using namespace::std;


//不包括有虚方法的派生
struct Base{};
struct Derived:Base{};
//包括有虚方法的派生
struct Poly_Base {virtual void Member(){}};
struct Poly_Derived: Poly_Base{};
// 在 C++ 中struct与class除了默认访问权限不一样，其他的功能等效。
// struct默认的方问权限是public,而class默认是private.

//用于嵌套类型
class One{
public:
    class Nested{};
    Nested* n;
public:
    One(){ n= new Nested;}
    ~One(){delete  n;}
    Nested* N(){return n;}
};

//用于多重继承
class A1{
public:
    virtual void foo(){}
};
class A2{
public:
    virtual void bar(){}
};

class Mi : public A1,public A2{};

class Mi2:public Mi{};

//



//关于typeid的功能与应用,运行时类型识别(判断某个对象是那个类的对象)
void test_typeid()
{
    int i;
    int *pi;
    float *fi;
    //内置类型
    cout <<" int is: " <<typeid(int).name() << endl;//int 类型的名字是 i
    cout <<" int is: " <<typeid(i).name() << endl;//int 类型的变量的类型名字是 i
    cout <<" pi is: " <<typeid(pi).name() << endl;//指向int类型的指针的类型是 Pi //P 表示指针
    cout <<" *pi is: " <<typeid(*pi).name() << endl;//对int类型的指针取值,当然是int类型，所以是i
    cout <<" void is: " <<typeid(void).name() <<endl;//void的名字是v
    cout <<" fi is: " <<typeid(fi).name() <<endl;//Pf
    cout <<" *fi is: " <<typeid(*fi).name() <<endl;// f 其他的内置类型,用同样的方法可以测出
    
    //运用时一般是如下方式，判断是否属于某类型。
    cout << boolalpha <<"same type ?";
    cout <<" typeid(47) == typeid(int) 是真值: " << (typeid(47) == typeid(int)) <<endl;
    cout <<" typeid(i) == typeid(int) 是真值: " << (typeid(i) == typeid(int)) <<endl;
    cout <<" typeid(&i) == typeid(int*) 是真值: " << (typeid(&i) == typeid(int*)) <<endl;
    
    cout <<endl;
    //非多态
    Derived derived;
    Base * pbase = &derived;
    cout <<" derived is: " <<typeid(derived).name() <<endl;
    cout <<" *pbase is: " <<typeid(*pbase).name() <<endl;
    cout << boolalpha <<"same type ?";
    cout <<" 由于没有虚函数，所以 typeid(*pbase) == typeid(derived) 的真值是: "
        << (typeid(*pbase) == typeid(derived)) << "它们不是同一类型，这种结果，不是我们想要的，我们希望它们相等" <<endl;
    cout << endl;
    
    //有虚函数的继承,
    Poly_Base polyderived;
    Poly_Base* ppolybase = &polyderived;
    cout <<" polyderived is: " <<typeid(polyderived).name() <<endl;
    cout <<" *ppolybase is: " <<typeid(*ppolybase).name() <<endl;
    cout <<" 基类指针的取值，进行类型判断，得到它的真实类型，即派生类型。是我们想要的"<<endl;
    cout <<" typeid(*ppolybase) == typeid(polyderived) 的真值是:"<< (typeid(*ppolybase) == typeid(polyderived))<<endl;
    cout <<endl;
    //因此总结:对于没有虚函数的类型进行判别时typeid(),不能判别出真实的类型。这里不是它的应用场所.
    //它用于带有虚函数的的，类型对象的判断时，才能准确得出所属的类型。
    
    
    One one;
    cout <<" one.N() 返回值是指针，再对其取值，则得到的是内部类 Nested的对象,它的名字，肯定是指：one类的嵌套类Nested类的对象"
        << typeid( *one.N()).name() <<endl;
    cout << typeid(One::Nested).name() <<endl;
    cout <<" typeid( *one.N()).name() == typeid(One::Nested).name() 是真值:"
         <<(typeid( *one.N()).name() == typeid(One::Nested).name()) << endl;
    
    cout <<endl;
    
    A2* a2 = new Mi2;//基类指针，指向第三级继承的对象
    Mi2* mi2 = dynamic_cast<Mi2*>(a2);//从基类指针，动态转型回来，ok
    Mi* mi = dynamic_cast<Mi*>(a2);//转换到第二级指针。也可以
    
    A1* a1 = dynamic_cast<A1*>(a2);//动态转换两个第一级基类指针.原因是a2所指的对象，继承了A1,A2.
    
    if(mi2){
        cout <<"dynamic_cast<Mi2*>(a2) is ok" <<endl;
    }
    if(mi){
        cout <<"dynamic_cast<Mi*>(a2) is ok" <<endl;
    }
    if(a1){
        cout <<"dynamic_cast<A1*>(a2) is ok" <<endl;
    }
    
    cout <<" typeid(a2) != typeid(Mi2*)值是: "<< (typeid(a2) != typeid(Mi2*))
        <<" 这个指针类型是不相等的。不像dynami_cast可以进行动态转换"<<endl;
    cout << "但是对象类型是一样的: typeid(*a2) == typeid(Mi2) " <<(typeid(*a2) == typeid(Mi2)) <<endl;
    cout << "但是对象类型不一样: typeid(*a2) == typeid(Mi1) " <<(typeid(*a2) == typeid(Mi)) <<endl;
    
    
    cout <<"总之一句话:typeid(),测试对象类型时，是创建该对象的类型。即 new T(),即 T类型,前提是包括有虚函数" <<endl;
    cout <<"不包虚函数的类型继承类的测试,typeid()不准确"<<endl;
    
}


void test_miscells()
{
    test_typeid();



}